package cn.imvc.app.controllers;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


import cn.imvc.app.domains.AppResult;
import cn.imvc.app.domains.OrderState;
import cn.imvc.app.domains.OrderType;
import cn.imvc.app.entities.Account;
import cn.imvc.app.entities.DealerApply;
import cn.imvc.app.entities.GoodsOrder;
import cn.imvc.app.entities.Member;
import cn.imvc.app.entities.Orders;
import cn.imvc.app.entities.Recharge;
import cn.imvc.app.models.AccountModel;
import cn.imvc.app.models.DealerApplyModel;
import cn.imvc.app.models.MemberModel;
import cn.imvc.app.models.OrderModel;
import cn.imvc.app.models.PayModel;
import cn.imvc.app.models.RechargeModel;
import cn.imvc.core.ICache;
import cn.imvc.core.Render;
import cn.imvc.ipay.IPayChannel;
import cn.imvc.ipay.Payment;
import cn.imvc.util.CookieTools;
import cn.imvc.util.RequestBody;
import me.hao0.alipay.model.AlipayFields;
import me.hao0.alipay.model.enums.AlipayField;
import me.hao0.wepay.core.Wepay;
import me.hao0.wepay.util.Maps;

@Controller
@RequestMapping("pay")
public class PayControllerImpl implements PayController {
	
	private static final Logger log = Logger.getLogger(PayControllerImpl.class);

	@Autowired
	MemberModel memberModel;

	@Autowired
	AccountModel accountModel;

	@Autowired
	DealerApplyModel dealerApplyModel;

	@Autowired
	OrderModel orderModel;

	@Autowired
	PayModel payModel;

	@Autowired
	RechargeModel rechargeModel;

	@Autowired
	Payment payment;

	@Autowired
	ICache icache;
	
	@RequestMapping("payPage.htm")
	public String pcpayPage(Model model, String token, String code) {
		// 用户未登录状态直接跳转登陆页面
		if (token == null || !memberModel.checkLogin(token)) {
			return "redirect:/member/login.htm";
		}
		model.addAttribute("code", code);
		return "pay/pcpayPage";
	}

	// 选择支付方式的页面
	@RequestMapping("pay.html")
	public String pay(Model model, String token, String orderCode, HttpServletRequest request) {
		// 用户未登录状态直接跳转登陆页面
		if (token == null || !memberModel.checkLogin(token)) {
			return "redirect:/member/login.html";
		}
		// 通过token从缓存里取member
		Member member = memberModel.getLoginMember(token);
		member = memberModel.get(member.getId());
		Integer money = 0;

		String type = orderCode.substring(0, 2);
		if (OrderType.Upgrade.getValue().equals(type)) {
			model.addAttribute("upgrade", true);
			model.addAttribute("purse", true);
			DealerApply dealerApply = dealerApplyModel.findByCode(orderCode);
			money = dealerApply.getJoinMoney();

		} else if (OrderType.Order.getValue().equals(type)) {
			model.addAttribute("purse", true);
			Orders orders = orderModel.findByCode(orderCode);
			money = orders.getResultAmount();
			model.addAttribute("express", orders.getFreightAmount());

		} else if (OrderType.Recharge.getValue().equals(type)) {
			model.addAttribute("purse", false);
			Recharge recharge = rechargeModel.findByCode(orderCode);
			money = recharge.getMoney();
		}
		model.addAttribute("money", money);
		model.addAttribute("code", orderCode);
		model.addAttribute("account", member.getAccount());
		model.addAttribute("key", member.getAccount().getKey1());
		String ua = request.getHeader("user-agent").toLowerCase();
		if (ua.indexOf("micromessenger") > 0) {
			model.addAttribute("weixin", true);
		} else {
			model.addAttribute("weixin", false);
		}

		if (ua.indexOf("androidapp") > 0 || ua.indexOf("applewebkitapp") > 0) {
			model.addAttribute("androidapp", true);

		}
		return "pay/pay";
	}

	// 余额支付
	@RequestMapping("balancePay.json")
	@ResponseBody
	public Map<String, Object> balancePay(String token, String payPass, String code) {
		Map<String, Object> resultMap = new HashMap<String, Object>();

		// 用户未登录状态直接跳转登陆页面
		if (token == null || !memberModel.checkLogin(token)) {
			resultMap.put("code", "-1");
			resultMap.put("msg", "未登录");
			return resultMap;
		}
		// 通过token从缓存里取member
		Member member = memberModel.getLoginMember(token);
		member = memberModel.get(member.getId());
		Account account = member.getAccount();

		if (account.getPaypwd() == null || "".equals(account.getPaypwd())) {
			resultMap.put("code", "0");
			resultMap.put("msg", "请设置支付密码");
			return resultMap;
		}
		if (!accountModel.checkPayPw(account, payPass)) {
			resultMap.put("code", "0");
			resultMap.put("msg", "支付密码错误");
			return resultMap;
		}
		try {
			resultMap = payModel.balancePay(code, member).toMap();
		} catch (Exception e) {
			log.error("code"+code+"    "+e.toString());
			resultMap.put("code", "0");
			resultMap.put("msg", "账户异常");
			return resultMap;
		}

		return resultMap;
	}

	// 支付宝支付
	@RequestMapping("moneyPay.json")
	@ResponseBody
	public Map<String, Object> moneyPay(HttpServletRequest request, String token, String code, byte payChannel) {
		Map<String, Object> resultMap = new HashMap<String, Object>();

		// 用户未登录状态直接跳转登陆页面
		if (token == null || !memberModel.checkLogin(token)) {
			resultMap.put("code", "-1");
			resultMap.put("msg", "未登录");
			return resultMap;
		}
		// 通过token从缓存里取member
		Member member = memberModel.getLoginMember(token);
		member = memberModel.get(member.getId());

		Integer money = payModel.setOrderPayment(code, payChannel);
		if (money == 0) {
			resultMap.put("code", "0");
			resultMap.put("msg", "支付失败");
			return resultMap;
		}

		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		String type = code.substring(0, 2);
		String body = "";
		if (OrderType.Upgrade.getValue().equals(type)) {
			body = "分销商升级订单";
		} else if (OrderType.Order.getValue().equals(type)) {
			body = "商品订单";
		} else if (OrderType.Recharge.getValue().equals(type)) {
			body = "充值订单";
		}
		String openId = "";
		Cookie userAccessToken = CookieTools.getCookieByName(request, "user_access_token");
		if (userAccessToken != null) {
			openId = icache.getSecond("WEIXIN_CACHE", userAccessToken.getValue());
		}

		String form = payment.create(code, money, IPayChannel.get(payChannel),
				ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip, body, openId);
		resultMap.put("code", "1");
		resultMap.put("msg", "成功");
		resultMap.put("form", form);
		return resultMap;
	}

	// 支付宝异步返回结果
	@RequestMapping("alipayResult.json")
	@ResponseBody
	public String alipayResult(HttpServletRequest request) {
		Map<String, String> notifyParams = new HashMap<>();

		// TODO 这里还是建议直接从request中获取map参数，兼容支付宝修改或增减参数
		for (AlipayField f : AlipayFields.WEB_PAY_NOTIFY) {
			notifyParams.put(f.field(), request.getParameter(f.field()));
		}
		if (!payment.getAlipay().checkParams(notifyParams)) {
			return Render.text("fail");
		}

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("code", request.getParameter("out_trade_no"));
		try {
			map.put("time", sdf.parse(request.getParameter("gmt_payment").toString()));
		} catch (ParseException e) {
			map.put("time", new Date());
			e.printStackTrace();
		}
		Double money = Double.parseDouble(request.getParameter("total_fee").toString());
		map.put("money", (int) (money * 100));
		map.put("payCode", request.getParameter("trade_no"));
		map.put("is_success", "TRADE_SUCCESS".equals(request.getParameter("trade_status")));
		if (!"TRADE_SUCCESS".equals(request.getParameter("trade_status"))) {
			return Render.text("success");
		}
		try {
			AppResult appResult=payModel.moneyPay(map);
			log.info("code"+map.get("code").toString()+"   "+appResult.getMsg());
		} catch (Exception e) {
			log.error("code"+map.get("code").toString()+"   "+e.toString());
			Render.text("failed");
		}
		return Render.text("success");
	}

	// 手机支付页面
	@RequestMapping("result.html")
	public String result(HttpServletRequest request, String result, Model model) {
		model.addAttribute("result", "false".equals(result) ? false : true);
		return "pay/result";
	}

	// pc支付页面
	@RequestMapping("result.htm")
	public String pcresult(HttpServletRequest request, String result, Model model) {
		model.addAttribute("result", "false".equals(result) ? false : true);
		return "pay/pcresult";
	}

	// 微信异步返回结果
	@RequestMapping("wxpayResult.json")
	@ResponseBody
	public String wxpayResult(HttpServletRequest request) {

		Wepay wepay = payment.getWxpay().getWepay();
		String notifyXml = RequestBody.getPostRequestBody(request);
		if (notifyXml.isEmpty()) {
			return Render.text(wepay.notifies().notOk("body为空"));
		}

		Map<String, Object> notifyParams = Maps.toMap(notifyXml);

		if (payment.getWxpay().checkParams(notifyParams)) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("code", notifyParams.get("out_trade_no"));
			try {
				map.put("time", sdf.parse(notifyParams.get("time_end").toString()));
			} catch (ParseException e) {
				map.put("time", new Date());
				e.printStackTrace();
			}
			map.put("money", Integer.parseInt(notifyParams.get("total_fee").toString()));
			map.put("payCode", notifyParams.get("transaction_id"));
			map.put("is_success", "SUCCESS".equals(notifyParams.get("result_code")));
			if (!"SUCCESS".equals(notifyParams.get("result_code"))) {
				return Render.text(wepay.notifies().ok());
			}
			try {
				AppResult appResult =payModel.moneyPay(map);
				log.info("code"+map.get("code").toString()+"   "+appResult.getMsg());
			} catch (Exception e) {
				log.error("code"+map.get("code").toString()+"   "+e.toString());
				return Render.text(wepay.notifies().notOk("回调处理失败"));
			}

			return Render.text(wepay.notifies().ok());
		} else {
			return Render.text(wepay.notifies().notOk("签名失败"));
		}

	}

	// 选择支付方式的页面
	@RequestMapping("pay.htm")
	public String pcpay(Model model, String token, String orderCode, HttpServletRequest request) {
		// 用户未登录状态直接跳转登陆页面
		if (token == null || !memberModel.checkLogin(token)) {
			return "redirect:/member/login.htm";
		}
		// 通过token从缓存里取member
		Member member = memberModel.getLoginMember(token);
		member = memberModel.get(member.getId());
		Integer money = 0;

		String type = orderCode.substring(0, 2);
		if (OrderType.Upgrade.getValue().equals(type)) {
			model.addAttribute("upgrade", true);
			model.addAttribute("purse", true);
			DealerApply dealerApply = dealerApplyModel.findByCode(orderCode);
			money = dealerApply.getJoinMoney();

		} else if (OrderType.Order.getValue().equals(type)) {
			model.addAttribute("purse", true);
			Orders orders = orderModel.findByCode(orderCode);
			money = orders.getResultAmount();
			model.addAttribute("express", orders.getFreightAmount());
			model.addAttribute("goodsMoney", orders.getGoodsAmount());
			model.addAttribute("discount", orders.getDiscountAmount());
			Set<GoodsOrder> goodsOrderList = orders.getGoodsOrder();
			Integer count = 0;
			for (GoodsOrder goodsOrder : goodsOrderList) {
				count = count + goodsOrder.getNum();
			}
			model.addAttribute("num", count);

		} else if (OrderType.Recharge.getValue().equals(type)) {
			model.addAttribute("purse", false);
			Recharge recharge = rechargeModel.findByCode(orderCode);
			money = recharge.getMoney();
		}
		model.addAttribute("money", money);
		model.addAttribute("code", orderCode);
		model.addAttribute("account", member.getAccount());
		model.addAttribute("key", member.getAccount().getKey1());
		return "pay/pcpay";
	}

	// 异步返回结果
	@RequestMapping("checkOrder.json")
	@ResponseBody
	public Map<String, Object> checkOrder(Model model, String token, String code) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		// 用户未登录状态直接跳转登陆页面
		if (token == null || !memberModel.checkLogin(token)) {
			resultMap.put("code", "-1");
			resultMap.put("msg", "未登录");
			return resultMap;
		}
		Recharge recharge = rechargeModel.findByCode(code);
		if(recharge!=null&&recharge.getState()==OrderState.PaySuccess.getValue()){
			resultMap.put("code", "1");
			resultMap.put("msg", "成功");
			return resultMap;
		}
		Orders order = orderModel.findByCode(code);
		if(order!=null&&(order.getState()==OrderState.PaySuccess.getValue()||(order.getState()==OrderState.Delivery.getValue()))){
			resultMap.put("code", "1");
			resultMap.put("msg", "成功");
			return resultMap;
		}
		DealerApply dealerApply = dealerApplyModel.findByCode(code);
		if(dealerApply!=null&&dealerApply.getState()==OrderState.PaySuccess.getValue()){
			resultMap.put("code", "1");
			resultMap.put("msg", "成功");
			return resultMap;
		}
		resultMap.put("code", "0");
		resultMap.put("msg", "未成功");
		return resultMap;
	}

}
